package x.ovo.wechat.bot;

import lombok.extern.slf4j.Slf4j;
import x.ovo.wechat.bot.common.command.Command;
import x.ovo.wechat.bot.common.command.CommandExecutor;
import x.ovo.wechat.bot.common.entity.message.TextMessage;
import x.ovo.wechat.bot.common.plugin.Plugin;

/**
 * 内存命令执行器
 *
 * @author ovo on 2024/05/11.
 * @since 1.0.0
 */
@Slf4j(topic = "内存管理")
public class MemoryCommandExecutor extends CommandExecutor {
    protected MemoryCommandExecutor(Plugin plugin) {
        super(plugin);
    }

    @Override
    public void execute(Command command, TextMessage message) {
        String fromName = command.getFromName();
        String[] args = command.formatArgs();

        if (!inAuthors(fromName)) {
            this.context.getApi().sendText(message.getFromUser().getUserName(), "你没有权限执行此命令，不要调皮");
            return;
        }

        try {
            if (args.length == 0 || args[0].equals("help")) {
                this.context.getApi().sendText(message.getFromUser().getUserName(), help());
            } else if (args[0].equals("show")) {
                this.context.getApi().sendText(message.getFromUser().getUserName(), show());
            } else if (args[0].equals("clear")) {
                this.context.getApi().sendText(message.getFromUser().getUserName(), clear());
            } else {
                this.context.getApi().sendText(message.getFromUser().getUserName(), "未知命令");
            }
        } catch (Exception e) {
            log.error("命令执行失败", e);
            this.context.getApi().sendText(message.getFromUser().getUserName(), "命令执行失败" + e.getMessage());
        }
    }

    private String help() {
        return """
                [内存管理]插件帮助：
                help        显示帮助
                show        显示内存使用情况
                clear       执行GC
                """;
    }

    private String show() {
        String memory = formatSize(Runtime.getRuntime().totalMemory());
        log.info("当前内存占用：{}", memory);
        return "当前内存占用：" + memory;
    }

    private String clear() {
        String before = formatSize(Runtime.getRuntime().totalMemory());
        System.gc();
        String after = formatSize(Runtime.getRuntime().totalMemory());
        log.info("GC执行成功，执行前内存占用：{}，执行后内存占用：{}", before, after);
        return String.format("GC执行成功，执行前内存占用：%s，执行后内存占用：%s", before, after);
    }

    private static String formatSize(long size) {
        if (size < 1024) {
            return size + " B";
        }
        if (size < 1024 * 1024) {
            return Double.parseDouble(String.format("%.2f", size / 1024.0)) + " KB";
        }
        if (size < 1024 * 1024 * 1024) {
            return Double.parseDouble(String.format("%.2f", size / 1024.0 / 1024.0)) + " MB";
        }
        return Double.parseDouble(String.format("%.2f", size / 1024.0 / 1024.0 / 1024.0)) + " GB";
    }
}
